﻿using System.ComponentModel.DataAnnotations.Schema;
using NineMine.DataModel.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NineMine.Core;
using System.IO;
using log4net;

namespace NineMine.DataModel
{
    public class Attachment : IClonable<Attachment>, IDisposable
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Attachment));

        private HashHelper _hash = new HashHelper();

        [Key]
        public long Id { get; set; }

        public long ContainerId { get; set; }

        [MaxLength(30)]
        public string ContainerType { get; set; }

        [MaxLength(255), Required]
        public string FileName { get; set; }

        [MaxLength(255)]
        public string DiskFileName { get; set; }

        public long FileSize { get; set; }

        [MaxLength(255)]
        public string ContentType { get; set; }

        [MaxLength(40), Required]
        public string Digest { get; set; }

        public long Downloads { get; set; }

        [Required]
        public User Author { get; set; }

        public DateTime? CreatedOn { get; set; }

        [MaxLength(255)]
        public string Deescription { get; set; }

        [MaxLength(255)]
        public string DiskDirectory { get; set; }

        [NotMapped]
        public string AttachmentStoragePath
        {
            get { return Settings.Default.AttachmentStoragePath; }
        }

        public Attachment Clone()
        {
            return new Attachment
            {
                Author = Author,
                ContainerId = ContainerId,
                ContainerType = ContainerType,
                ContentType = ContentType,
                CreatedOn = CreatedOn,
                Deescription = Deescription,
                Digest = Digest,
                DiskDirectory = DiskDirectory,
                DiskFileName = DiskFileName,
                FileName = FileName,
                FileSize = FileSize,
                _attachmentFile = _attachmentFile
            };
        }

        private FileInfo _attachmentFile;

        [NotMapped]
        public FileInfo AttachmentFile
        {
            get { return _attachmentFile; }
            set
            {
                _attachmentFile = value;
                if (value != null)
                {
                    FileSize = value.Length;
                    ContentType = value.MimeTypeOf();
                    FileName = value.FullName;
                    using (var data = value.OpenRead())
                    {
                        Digest = _hash.GenerateHash(data);
                    }
                }
                else
                {
                    FileSize = 0;
                    ContentType = null;
                    FileName = null;
                    Digest = null;
                }
            }
        }

        [NotMapped]
        public string TargetDirectory
        {
            get
            {
                var time = CreatedOn.HasValue ? CreatedOn.Value : DateTime.Now;
                return time.ToString("yyyyMM");
            }
        }

        public bool IsOverMaxFileSize()
        {
            return !(_attachmentFile != null && (FileSize / 1024) > Settings.Default.AttachmentMaxSizeInKB);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _hash.Dispose();
            }
        }
    }
}
